package com.example.application.views.supplier;

import com.example.application.bean.*;
import com.example.application.views.util.MyHttpClientUtil;
import com.example.application.views.util.ShowAllInfosUtil;
import com.example.application.views.util.DialogUtil;
import com.example.application.views.util.VerifyUtil;
import com.example.page.PageComponent;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasStyle;
import com.vaadin.flow.component.Text;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.splitlayout.SplitLayout;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.converter.StringToIntegerConverter;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.PageTitle;
import com.example.application.views.main.MainView;
import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.html.Image;
import elemental.json.Json;
import com.vaadin.flow.component.html.Label;

import java.util.Base64;
import com.vaadin.flow.component.textfield.TextField;
import java.nio.charset.StandardCharsets;
import org.springframework.web.util.UriUtils;
import com.vaadin.flow.component.upload.Upload;
import java.io.ByteArrayOutputStream;

@Route(value = "supplier", layout = MainView.class)
@PageTitle("供应商管理")
@CssImport("./views/供应商管理/供应商管理-view.css")
public class SupplierView extends Div {

    private Grid<Supplier> grid = new Grid<>(Supplier.class, false);
    private Upload image;
    private Image imagePreview;
    private TextField supId;
    private TextField name;
    private TextField address;
    private TextField telNum;
    private TextField website;

    private int curPage = 1;
    private int pageSize = 2;
    private int tolNum;
    private int tolPage;
    private ObjectMapper mapper = new ObjectMapper();

    private Button cancel = new Button("取消");
    private Button save = new Button("保存");
    private Button delete = new Button("删除");
    private Button update = new Button("更新");

    private BeanValidationBinder<Supplier> binder;

    private Supplier supplier;

    //    @Autowired SupplierService supplierService
    public SupplierView() {
        User user = (User) UI.getCurrent().getSession().getAttribute("user");
        if (user == null){

        }else if("供应商管理员".equals(user.getIdentity()) || "平台管理员".equals(user.getIdentity())){
            this.init();
        }else{
            DialogUtil.adminAuthority();
        }
    }

    private void createEditorLayout(SplitLayout splitLayout) {
        Div editorLayoutDiv = new Div();
        editorLayoutDiv.setId("editor-layout");

        Div editorDiv = new Div();
        editorDiv.setId("editor");
        editorLayoutDiv.add(editorDiv);

        FormLayout formLayout = new FormLayout();
        Label imageLabel = new Label("Image");
        imagePreview = new Image();
        imagePreview.setWidth("100%");
        image = new Upload();
        image.getStyle().set("box-sizing", "border-box");
        image.getElement().appendChild(imagePreview.getElement());
        supId = new TextField("编号");
        name = new TextField("公司");
        telNum = new TextField("电话");
        address = new TextField("地址");
        website = new TextField("网址");

        Component[] fields = new Component[]{imageLabel, image, supId, name, telNum, address, website};

        for (Component field : fields) {
            ((HasStyle) field).addClassName("full-width");
        }
        formLayout.add(fields);
        editorDiv.add(formLayout);
        createButtonLayout(editorLayoutDiv);

        splitLayout.addToSecondary(editorLayoutDiv);
    }

    private void createButtonLayout(Div editorLayoutDiv) {
        HorizontalLayout buttonLayout = new HorizontalLayout();
        buttonLayout.setId("button-layout");
        buttonLayout.setWidthFull();
        buttonLayout.setSpacing(true);
        cancel.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
        save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        delete.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        update.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        buttonLayout.add(save, delete, update, cancel);
        editorLayoutDiv.add(buttonLayout);
    }

    private void createGridLayout(SplitLayout splitLayout) {
        Div wrapper = new Div();
        wrapper.setId("grid-wrapper");
        wrapper.setWidthFull();
        PageComponent pageComponent = new PageComponent(curPage, pageSize, SupplierView.this.tolNum, SupplierView.this.tolPage) {
            @Override
            protected void pageNext() {
                SupplierView.this.curPage = this.curPage;
                updateForm();
                init();
            }

            @Override
            protected void pagePrevious() {
                SupplierView.this.curPage = this.curPage;
                updateForm();
                init();
            }

            @Override
            protected void gotoPage() {

            }

            @Override
            protected void firstPage() {
                SupplierView.this.curPage = 1;
                updateForm();
                init();
            }

            @Override
            protected void lastPage() {
                SupplierView.this.curPage = this.tolPage;
                updateForm();
                init();
            }

            @Override
            protected void selectPage() {

            }
        };
        pageComponent.components.add(grid);
        pageComponent.init();
        splitLayout.addToPrimary(pageComponent);
    }

    private void attachImageUpload(Upload upload, Image preview) {
        ByteArrayOutputStream uploadBuffer = new ByteArrayOutputStream();
        upload.setAcceptedFileTypes("image/*");
        upload.setReceiver((fileName, mimeType) -> uploadBuffer);
        upload.addSucceededListener(e -> {
            String mimeType = e.getMIMEType();
            String base64ImageData = Base64.getEncoder().encodeToString(uploadBuffer.toByteArray());
            String dataUrl = "data:" + mimeType + ";base64,"
                    + UriUtils.encodeQuery(base64ImageData, StandardCharsets.UTF_8);
            upload.getElement().setPropertyJson("files", Json.createArray());
            preview.setSrc(dataUrl);
            uploadBuffer.reset();
        });
        preview.setVisible(false);
    }

    private void refreshGrid() {
        grid.select(null);
        grid.getDataProvider().refreshAll();
    }

    private void clearForm() {
        populateForm(null);
    }

    private void populateForm(Supplier value) {
        this.supplier = value;
        binder.readBean(this.supplier);
    }

    private void updateForm(){
        ResultBean<PageBean> resultBean = ShowAllInfosUtil.showInfos(SupplierUri.SUP, curPage, pageSize, Supplier.class);

        grid.setItems(resultBean.getT().getDatas());

        tolNum = resultBean.getT().getTolNum();

        tolPage = resultBean.getT().getTolPage();
    }

    public void init(){
        addClassName("供应商管理-view");
        // Create UI
        SplitLayout splitLayout = new SplitLayout();
        splitLayout.setSizeFull();

        this.updateForm();
        createGridLayout(splitLayout);
        createEditorLayout(splitLayout);

        add(splitLayout);

        // Configure Grid
        /*TemplateRenderer<Supplier> imageRenderer = TemplateRenderer
                .<Supplier>of("<img style='height: 64px' src='[[item.image]]' />")
                .withProperty("licensePic", Supplier::getLicensePic);*/
        grid.addColumn("supId").setHeader("编号").setAutoWidth(true);
        grid.addColumn("name").setHeader("公司").setAutoWidth(true);
        grid.addColumn("user.name").setHeader("名字").setAutoWidth(true);
        grid.addColumn("telNum").setHeader("电话").setAutoWidth(true);
        grid.addColumn("address").setHeader("地址").setAutoWidth(true);
        grid.addColumn("website").setHeader("网站").setAutoWidth(true);
        grid.addColumn("user.email").setHeader("邮箱").setAutoWidth(true);
        grid.addColumn("licensePic").setHeader("执照").setWidth("108px").setFlexGrow(0);
        grid.addThemeVariants(GridVariant.LUMO_NO_BORDER);
        grid.setHeightFull();

        // when a row is selected or deselected, populate form
        grid.asSingleSelect().addValueChangeListener(event -> {
            populateForm(event.getValue());
        });

        // Configure Form
        binder = new BeanValidationBinder<>(Supplier.class);

        binder.forField(supId).withConverter(new StringToIntegerConverter("必须输入数字")).bind("supId");
        binder.bindInstanceFields(this);

        attachImageUpload(image, imagePreview);

        cancel.addClickListener(e -> {
            clearForm();
            refreshGrid();
        });

        save.addClickListener(e -> {
            try {
                if(supplier != null){
                    supplier.setSupId(Integer.parseInt(supId.getValue().trim()));
                    supplier.setName(name.getValue().trim());
                    supplier.setAddress(address.getValue().trim());
                    supplier.setTelNum(telNum.getValue().trim());
                    supplier.setWebsite(website.getValue().trim());

                    if(this.verifyInfo(supplier)){
                        String msg = MyHttpClientUtil.httpPost(SupplierUri.SUP_ADD, supplier, "utf-8");
                        JavaType javaType = mapper.getTypeFactory().constructParametricType(ResultBean.class, String.class);
                        ResultBean resultBean = mapper.readValue(msg, javaType);

                        if(resultBean.getCode() != 0){
                            UI.getCurrent().getPage().executeJs("alert('添加成功');window.location.href='http://localhost:8080/supplier'");
                        }else {
                            UI.getCurrent().getPage().executeJs("alert('添加失败')");
                        }
                    }
                }
            }catch (Exception exception){
                exception.printStackTrace();
            }

            updateForm();
        });

        update.addClickListener(e -> {
            try {
                if(supplier != null){
                    supplier.setSupId(Integer.parseInt(supId.getValue().trim()));
                    supplier.setName(name.getValue().trim());
                    supplier.setAddress(address.getValue().trim());
                    supplier.setTelNum(telNum.getValue().trim());
                    supplier.setWebsite(website.getValue().trim());

                    if(verifyInfo(supplier)){
                        String msg = MyHttpClientUtil.httpPut(SupplierUri.SUP_UPDATE, supplier, "utf-8");
                        JavaType javaType = mapper.getTypeFactory().constructParametricType(ResultBean.class, String.class);
                        ResultBean resultBean = mapper.readValue(msg, javaType);

                        if(resultBean.getCode() != 0){
                            UI.getCurrent().getPage().executeJs("alert('更新成功');window.location.href='http://localhost:8080/supplier'");
                        }else {
                            UI.getCurrent().getPage().executeJs("alert('更新失败')");
                        }
                    }
                }
            }catch (Exception exception){
                exception.printStackTrace();
            }
            updateForm();
        });

        delete.addClickListener(e -> {
            Dialog dialog = new Dialog();
            dialog.setCloseOnEsc(false);
            dialog.setCloseOnOutsideClick(false);
            dialog.removeAll();
            dialog.add(new Text("确定要删除吗？"));

            Button okBtn = new Button("确定", sure ->{
//            执行删除操作
                try {
                    if(supplier.getId() != null){
                        String msg = MyHttpClientUtil.httpDelete(SupplierUri.SUP, supplier.getId(), "utf-8");
                        ResultBean resultBean = mapper.readValue(msg, ResultBean.class);
                        if(resultBean.getCode() != 0){
                            UI.getCurrent().getPage().executeJs("alert('删除成功');window.location.href='http://localhost:8080/supplier'");
                        }else {
                            UI.getCurrent().getPage().executeJs("alert('删除失败');");
                        }
                    }
                }catch (Exception exception){
                    exception.printStackTrace();
                }
                dialog.close();
            });

            Button noBtn = new Button("取消",e2->{
                dialog.close();
            });

            dialog.add(new Div(okBtn, new Text("      "), noBtn));
            dialog.open();
        });
    }

    public boolean verifyInfo(Supplier supplier){
        if(!VerifyUtil.lengthVerify(supplier.getName())){
            UI.getCurrent().getPage().executeJs("alert('公司名字长度不能超过10');");
            return false;
        }else if(!VerifyUtil.telePhoneNumVerify(supplier.getTelNum())){
            UI.getCurrent().getPage().executeJs("alert('电话格式不正确');");
            return false;
        }else if(!VerifyUtil.WebSiteVerify(supplier.getWebsite())){
            UI.getCurrent().getPage().executeJs("alert('网址格式不正确');");
            return false;
        }else {
            return true;
        }
    }
}